package com.ruoyi.web.controller.mobile;


import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.config.properties.RsaKeyProperties;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.util.RsaUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.mobile.user.domain.vo.*;
import com.ruoyi.sms.service.DynamicMessageService;
import com.ruoyi.system.service.impl.MobileUserServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.rmi.ServerException;
import java.security.PrivateKey;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.ruoyi.common.core.domain.AjaxResult.success;

@RestController
@RequestMapping("/h5/user")
@Api(tags = "【新】H5用户相关接口")
public class UserController  extends BaseController {

    @Autowired
    private SysLoginService loginService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private MobileUserServiceImpl userService;
    @Resource
    private DynamicMessageService smsService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private RsaKeyProperties rsaKeyProperties;



    @ApiOperation("用户登录[短信登陆如果没有账号直接注册一个]")
    @PostMapping("/login")
    public AjaxResult<Map<String, Object>> registerLogin(@RequestBody UserLoginVO userLoginVO){
        Map<String, Object> map = new HashMap<>();
         map.put(Constants.TOKEN, loginService.login_h5_user(userLoginVO));
        return AjaxResult.success(map);
    }

    @ApiOperation("退出登录")
    @PostMapping("/login_out")
    public AjaxResult<String> loginOut(HttpServletRequest request, HttpServletResponse response){
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser)) {
            String userName = loginUser.getUsername();
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken());
            // 记录用户退出日志
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
        }
        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message("user.logout.success"))));
        return AjaxResult.success();
    }

    @ApiOperation("验证短信验证码")
    @PostMapping("/validate_code")
    public AjaxResult<String> senCode(@ApiParam(value = "参数")  @RequestBody SendCodeValidateVO validateVO) throws Exception {
        String code= redisCache.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY +"_"+validateVO.getPhone()+"_"+validateVO.getSmsType());
        if(StringUtils.isEmpty(code)){
            AjaxResult.error("短信验证码不正确或已失效!");
        }
        if(validateVO.getSmsType()==2){
            SysUser sysUser=userService.selectUserByPhone(validateVO.getPhone());
            if(sysUser==null){
                throw new ServiceException("该手机号码还未注册！");
            }
        }
        redisCache.deleteObject(CacheConstants.CAPTCHA_CODE_KEY +"_"+validateVO.getPhone()+"_"+validateVO.getSmsType());
        return AjaxResult.success();
    }



    @ApiOperation("查询当前用户信息")
    @GetMapping("/one")
    public AjaxResult<UserVO> getOne(){
        UserVO userVO=userService.getOne();
        return AjaxResult.success(userVO);
    }

    @ApiOperation("更新用户名称")
    @PostMapping("/update_name")
    public AjaxResult<String> updateName(@RequestBody UpdateUserNameVO userNameVO){
        userService.updateName(userNameVO);
        return AjaxResult.success();
    }


    @ApiOperation("更新用户密码")
    @PostMapping("/update_password")
    public AjaxResult<String> updatePassword(@RequestBody UpdateUserPasswordVO updateUserPasswordVO) throws Exception {

        if(StringUtils.isBlank(updateUserPasswordVO.getOldPassword())){
            throw new ServerException("旧密码不能为空");
        }
        PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
        updateUserPasswordVO.setOldPassword(RsaUtils.decrypt(updateUserPasswordVO.getOldPassword(), privateKey));


        if(StringUtils.isBlank(updateUserPasswordVO.getNewPassword())){
            throw new ServerException("新密码不能为空");
        }
        updateUserPasswordVO.setNewPassword(RsaUtils.decrypt(updateUserPasswordVO.getNewPassword(), privateKey));

        userService.updateUserPasswordVO(updateUserPasswordVO);
        return AjaxResult.success();
    }


    @ApiOperation("通过手机更新用户密码")
    @PostMapping("/update_password_by_phone")
    public AjaxResult<String> update_password_by_phone(@RequestBody UpdateUserPasswordPhoneVO phoneVO) throws Exception {


        PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
        if(StringUtils.isBlank(phoneVO.getNewPassword())){
            throw new ServerException("新密码不能为空");
        }
        phoneVO.setNewPassword(RsaUtils.decrypt(phoneVO.getNewPassword(), privateKey));

        userService.updateUserPasswordPhone(phoneVO);
        return AjaxResult.success();
    }


    @ApiOperation("换绑手机号码")
    @PostMapping("/binding_phone")
    public AjaxResult<String> bindingPhone(@RequestBody UserCodeVO userCodeVO){
        userService.bindingPhone(userCodeVO);
        return AjaxResult.success();
    }


    @ApiOperation("发送短信验证码")
    @PostMapping("/sen_code")
    public AjaxResult<String> senCode(@ApiParam(value = "参数")  @RequestBody SendCodeVO sendCodeVO) throws Exception {
        if(sendCodeVO.getSmsType()==2){
            SysUser sysUser= userService.selectUserByPhone(sendCodeVO.getPhone());
            if(sysUser==null){
                AjaxResult.error("手机未注册!");
            }
        }
        String code= RandomUtil.randomNumbers(4);
        logger.info(sendCodeVO.getPhone()+":::::发送短信验证码::::"+code);
        redisCache.setCacheObject(CacheConstants.CAPTCHA_CODE_KEY +"_"+sendCodeVO.getPhone()+"_"+sendCodeVO.getSmsType(),code,60*30, TimeUnit.SECONDS);
        try{

            switch (sendCodeVO.getSmsType()){
                case 1:
                    smsService.sendDynamicMessage("【光影重庆】您好，您此次验证码为:"+code+"，请不要把验证码泄漏给其他人，如非本人请勿操作。",sendCodeVO.getPhone());
                    break;
                case 2:
                    smsService.sendDynamicMessage("【光影重庆】您正在找回密码，验证码为："+code+"，请不要把验证码泄露给其他人。如非本人操作，可不用理会！",sendCodeVO.getPhone());
                    break;
                case 3:
                    smsService.sendDynamicMessage("【光影重庆】手机号变更验证码："+code+"，请勿泄露。如非本人操作，可不用理会！",sendCodeVO.getPhone());
                    break;
                case 4:
                    smsService.sendDynamicMessage("【光影重庆】手机绑定验证码为"+code+"，请不要把验证码泄露给其他人。如非本人操作，可不用理会！",sendCodeVO.getPhone());
                    break;
            }

        }catch (Exception e){
            e.printStackTrace();
            return  AjaxResult.success(code);
        }
        return AjaxResult.success();
    }


}
